﻿using System;
using System.Collections.Generic;
using System.Xml;

namespace ZCConsole
{
    public class RailSwitch : Device, IOccupy
    {
        public RailSwitch()
        {
            IsPositionNormal = false;
            IsPositionReverse = false;
            axleOccupy_ = true;
        }

        public bool IsPositionNormal { get; set; }
        public bool IsPositionReverse { get; set; }
        public bool Islock { get; set; }
        public bool IsAccessLock { get; set; }

        public enum SwitchPosition
        {
            PosNormal,
            PosReverse,
            PosNeither,
            PosFailure,
        }

        public int Direction { get; set; }
        /// <summary>
        /// 所属区段
        /// </summary>
        public Section section { get; private set; }

        /// <summary>
        /// 双动道岔
        /// </summary>
        public RailSwitch DoubleSwitch { get; private set; }

        /// <summary>
        /// 默认方向
        /// </summary>
        public Section.DefaultDirection DefDirection { get; private set; }

        /// <summary>
        /// 定位公里标长度
        /// </summary>
        public double NormalDistance { get; private set; }

        /// <summary>
        /// 反位公里标长度
        /// </summary>
        public double ReverseDistance { get; private set; }

        /// <summary>
        /// 是否朝上
        /// </summary>
        public bool IsUp { get; private set; }

        /// <summary>
        /// 是否朝左
        /// </summary>
        public bool IsLeft { get; private set; }

        private bool axleOccupy_;
        public bool AxleOccupy
        {
            get { return axleOccupy_; }
            set
            {
                if (axleOccupy_ != value)
                {
                    axleOccupy_ = value;
                    //if (RelateAxle != null)
                    //{
                    //    System.Windows.Application.Current.Dispatcher.Invoke(new Action(delegate
                    //    {
                    //        RelateAxle.InvalidateVisual();
                    //    }));
                    //}
                }
            }
        }

        List<UInt16> hasNonComTrain_ = new List<UInt16>();
        public List<UInt16> HasNonComTrain
        {
            get { return hasNonComTrain_; }
            set
            {
                if (hasNonComTrain_ != value)
                {
                    hasNonComTrain_ = value;
                }
            }
        }

        private List<UInt16> trainOccupy_ = new List<UInt16>();
        public List<UInt16> TrainOccupy
        {
            get { return trainOccupy_; }
        }

        private List<UInt16> isAccess_ = new List<UInt16>();
        public List<UInt16> IsAccess
        {
            get { return isAccess_; }
            set
            {
                if (isAccess_ != value)
                {
                    isAccess_ = value;
                }
            }
        }


        public override void LoadData(XmlElement element)
        {
            base.LoadData(element);

            section = new Section()
            {
                Name = element.GetAttribute("SectionName"),
                Id = int.Parse(element.GetAttribute("SectionID")),
                CiId = this.CiId,
            };

            string doubleName = element.GetAttribute("DoubleName");
            if (!string.IsNullOrEmpty(doubleName))
            {
                DoubleSwitch = new RailSwitch()
                {
                    Name = doubleName,
                    Id = int.Parse(element.GetAttribute("DoubleID"))
                };
            }

            DefDirection = (Section.DefaultDirection)Enum.Parse(
                typeof(Section.DefaultDirection), element.GetAttribute("Direction"));
            section.Direction = Direction;
            NormalDistance = int.Parse(element.GetAttribute("NormalDistance"));
            ReverseDistance = int.Parse(element.GetAttribute("ReverseDistance"));
            IsUp = bool.Parse(element.GetAttribute("IsUp"));
            IsLeft = bool.Parse(element.GetAttribute("IsLeft"));
        }

        public override void Initialize(List<Device> devices)
        {
            if (DoubleSwitch != null)
            {
                DoubleSwitch = (RailSwitch)devices.Find((Device device) =>
                {
                    if (device is RailSwitch)
                    {
                        return device.Name == DoubleSwitch.Name && device.Id == DoubleSwitch.Id;
                    }
                    return false;
                });
            }
        }

        /// <summary>
        /// 设置列车占用状态（道岔）
        /// </summary>
        /// <param name="trainID"></param>
        /// <param name="isOccupy"></param>
        public void SetTrainOccupy(UInt16 trainID, bool isOccupy)
        {
            SetTrainList(trainOccupy_, isOccupy, trainID);
        }

        public bool GetTrainOccupy(UInt16 trainID)
        {
            if (HasOtherTrain(trainOccupy_, trainID))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private bool HasOtherTrain(List<UInt16> list, UInt16 trainID)
        {
            if (list.Count == 0)
            {
                return false;
            }
            else if (list.Count == 1 && list.Contains(trainID))
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public UInt16 GetOffset(TrainDir Direction)
        {
            if (this.section.Name == "W0105" || this.section.Name == "W0106" || this.section.Name == "W0411" || this.section.Name == "W0414")
            {
                if (this.IsPositionNormal && !this.IsPositionReverse)
                {
                    return Convert.ToUInt16(2 * this.NormalDistance);
                }
                else if (this.IsPositionReverse && !this.IsPositionNormal)
                {
                    return Convert.ToUInt16(2 * this.ReverseDistance);
                }
                else
                {
                    return 0;
                }
            }
            else
            {
                if (this.IsPositionNormal && !this.IsPositionReverse)
                {
                    return Convert.ToUInt16(this.NormalDistance);
                }
                else if (!this.IsPositionNormal && this.IsPositionReverse)
                {
                    return Convert.ToUInt16(this.ReverseDistance);
                }
                else
                {
                    return 0;
                }
            }
        }

        public void SetNonCommunicateTrain(UInt16 trainID, bool isNonCom)
        {
            SetTrainList(hasNonComTrain_, isNonCom, trainID);
        }

        /// <summary>
        /// 将占用的列车ID存入列表中以及将非占用车移出列表
        /// </summary>
        /// <param name="trainList"></param>
        /// <param name="isOccupy"></param>
        /// <param name="trainID"></param>
        private void SetTrainList(List<UInt16> trainList, bool isOccupy, UInt16 trainID)
        {
            if (isOccupy)
            {
                if (!trainList.Contains(trainID))
                {
                    trainList.Add(trainID);
                }
            }
            else
            {
                if (trainList.Contains(trainID))
                {
                    trainList.Remove(trainID);
                }
            }
        }

        public void SetRouteOpen(UInt16 trainID, bool isOpen)
        {
            SetTrainList(isAccess_, isOpen, trainID);
        }


    }
}
